/*
 * @FilePath: /etws-sxk2307/inc/Hardware.h
 * @Description:  
 * @Author: ipk518 && 18163976442@163.com
 * @Date: 2024-05-22 16:44:47
 * @LastEditors: ipk518 18163976442@163.com
 * @LastEditTime: 2024-08-29 17:05:13
 * Copyright    : G AUTOMOBILE RESEARCH INSTITUTE CO.,LTD Copyright (c) 2024.
 */
#ifndef __HARDWARE_H_
#define __HARDWARE_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <queue>
#include <mutex>

#include "Bdpara.h"
#include "Common.h"
#include "../Middlewares/dataTransmission/uartLite/uartLite.h"

//radar_uart_block_radar_gps_uart=0x80040000
//radar_uart_block_radar_servo_uart=80050000

#if 1
//正常项目的串口配置
#define SERVO_NAME "/dev/ttyUL2"
#define GNSS_NAME "/dev/ttyUL1"
#else
//挂飞项目的串口配置
#define SERVO_NAME "/dev/ttyUL1"
#define GNSS_NAME "/dev/ttyUL2"
#endif

#define PL_LOCK_GPIO    0x80090000
#define PL_RESET_GPIO    0x80080000

#define PL_VERSION_BASEADDR                                             0x80010000
#define AXIREG_LVDS_ERROR_BASEADDR                                      0xa0050000
#define HARDWARE_TEST_BASEADDR                                          0xa0020000
#define TIMING_CONFIG_BASEADDR                                          0xa0060000
#define BEAM_LIST_BASEADDR                                              0xA0040000
#define BEAM_PARAM_BASEADDR                                             0xA0000000
#define BEAM_PHASECODE_BASEADDR                                         0xa0026000


#define PL_DDR_BASEADDR                                                 0x500000000
//接收校准观测
#define RX_OBSIQ_BASEADDR                                               PL_DDR_BASEADDR+0x02400000
//接收校准
#define RX_CALIB_BASEADDR                                               PL_DDR_BASEADDR+0x01400000
#define RX_OBSIQ_TRIGGER_BASEADDR                                       0x80000000
#define RX_AUTOALIGN_BASEADDR                                           0xa0028000      //axi_bram_ac_coe
#define RX_MANUALALIGN_BASEADDR                                         0xa0024000      //axi_bram_ma_coe
#define RX_DBF_BASEADDR                                                 PL_DDR_BASEADDR+0x03000000      //axi_bram_pc_coe
#define DBF_OBSIQ_BASEADDR                                              PL_DDR_BASEADDR+0x03200000 
#define ADC_OBS_BASEADDR                                                PL_DDR_BASEADDR+0x03400000      //AD OB Mem Struct
#define RX_DBF_POINT_BASEADDR                                           0xa0022000      //dbf_dir_bram_ctrl  

//发射校准观测
#define TX_OBSIQ_BASEADDR                                               PL_DDR_BASEADDR+0x10000000
//发射校准
#define TX_CALIB_BASEADDR                                               PL_DDR_BASEADDR+0x01000000
#define DRAK_ROOM_BASEADDR                                              0x82000000


#define RF_SYNC_REQ_REG_BASEADDR                                         0xa0080000



//心跳时钟延时
#define HEARTBERT_TIME_US 500*1000

#define PROCESS_1S      ((1000*1000) / (HEARTBERT_TIME_US))
#define PROCESS_1R5S    ((1500*1000) / (HEARTBERT_TIME_US))
#define PROCESS_2S      (2000*1000 / (HEARTBERT_TIME_US))
#define PROCESS_3S      ((3000*1000) / (HEARTBERT_TIME_US))
#define PROCESS_5S      ((5000*1000) / (HEARTBERT_TIME_US))


struct memoryOperation
{
    uint64_t m_addr;
    uint32_t m_len;
    uint8_t m_buffer[1024];
};

#define RESET_NUM   7
//复位配置
enum resetType
{   
    m_all,
    m_hmc7044,
    m_lmx2820,
    m_ad9171,
    m_timingParam,
    m_dbf,
    m_beamList,
};

class Uio;
class servoMotor;
class gnss;

class Hardware
{
public:
    Hardware() = default;
    ~Hardware(){deInit();};
public://伺服控制
    int m_rs485De = 0;
    servoMotor *m_servo = nullptr;
    uartLite *m_mtUart = nullptr;
    gnss *m_gnssUart = nullptr;
public: //uio类
    Uio *m_uio = nullptr;
public:
    int memFd = 0;
    int m_resetCount = 0;
    uint8_t m_read[1024];
    uint8_t m_write[1024];
    
    //时序卡系统参数
    struct SXKHardWareInfo m_sxkInfo;
     //雷达系统参数
    struct bdpara m_radarSystemInfo;
    //控制寄存器
    struct SXKControlReg m_controlReg;
    //暗室测试参数
    struct SXKDarktsConfig m_datktsConf;

    struct HardwareTest m_sxkHardTest;
    //系统配置寄存器
    struct SysConfig m_sysConfig;
    
    //通道耦合系数下发结构
    // uint16_t m_rxCouplCoff[128][2];
    //通道校准系数下发结构
    // uint16_t m_rxCaliCoff[4][130];
    struct rxCalibCoefficient m_rxAutoCaliCoe[32];//内32通道,接收自动校准系数
    struct rxCalibCoefficient m_rxManualCaliCoe[32];//32通道，接收手动校准系数
    //接收DBF系数（Q+I有符号16位）+雷达发射频率精度0.1MHz，在无线通信中通常将实部称为 I (n-phase)分量，将虚部称为 Q (uadrature)分量。
    struct rxDbfcoefficient m_rxDbfCoff[512];//16波束*32波位=512个波束
    struct rxDbfcoefficient m_readRxDbfCoff[512];//16波束*32波位=512个波束
    uint32_t m_radarSendFreq;//雷达发射频率
    int m_rxDbfPoint[32][16];//32个波位16波束的波束指向配合DBF波位系数使用
    //32组波位参数+1组发射H校准参数+1组发射V校准+1组接收H+1组接收V
    uint16_t readBeamParam[36][512];
    uint16_t beamParamReg[36][512];
    //波位调度表
    uint8_t readBeamList[40];
    uint8_t beamList[40];
    //TR通道状态
    uint8_t trChannelStatus[2][16];

    calibParam m_calibParam;

    //相位编码器
    uint8_t m_phaseWriteNum;
    uint16_t m_phaseCode[4][32];
public:
    bool m_once = true;//仅执行一次的变量,一键断电清AD状态，避免下次上电后AD未初始化就使能。一键上电后需重新同步。
    bool m_isInit = false;
    bool isRunning = false;
    std::mutex m_sysRun;
    //初始化硬件参数
    bool Init();
    
    void dataInit();
    void gpioInit();
    //关闭硬件
    void deInit();
    void dataRelese();
    //运行硬件循环
    void run();
    void initADSync();

    void setSysTimingPara();
    void setHardwareTestPara();
    void setBeamListPara();
    void setBeamPara();
    void setDBFPara();
    void setManualCaliPara();
    void setAutoCaliPara();
    void setDBFPointPara();
    void setPhaseCodePara();

    //参数同步
    void hardwareSync();
    //硬件测试
    void hardwareTest();
    bool checkClockLockStatus();
    //获取硬件测试结果
    void getHardwareTestResult();
    //获取硬件测试结果
    void setHardwareTestResult();

    //获取PL硬件版本号
    void plVersion();
    //获取PS硬件版本号
    void psVersion();
    //获取LVDS通讯状态
    void getLVDSStatus();
    //检测PL 锁相环LOCKED
    bool getLockStatus();
    //电源控制
    void powerControl(bool enabled,int powerType,int powerNum);
    //时序卡转换雷象结构体
    void sxkConverLx();

    void calibrationBeamMode(int setBeam,bool enable);
    void changeBeamFreq(int setBeam,int freq);
    //复位
    bool plReset();
    bool psReset();
    bool initPlRfSync();
    bool resetInit(int rst);
    void darktsSwitch(bool ret);
    //读写PL硬件参数
    int plRead(struct memoryOperation& memOp);
    int plWrite(struct memoryOperation& memOp);
private:
    std::thread * servoFd; /* 接收线程*/
    static void servoProtocolTask(Hardware *args);
    void updateDate();


    int m_process1000ms = 0;
    int m_process1500ms = 0;
    int m_process2000ms = 0;
    int m_process3000ms = 0;
    int m_process5000ms = 0;

    void process_1000ms();
    void process_1500ms();
    void process_2000ms();
    void process_3000ms();
    void process_5000ms();

};



#endif